"""pytest配置文件"""
import asyncio
import os
from pathlib import Path
from typing import AsyncGenerator, Generator

import pytest
import pytest_asyncio
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from swiftshadow.models.database import db
from swiftshadow.models.task import Base, DownloadTask, TaskStatus
from swiftshadow.utils.logger import setup_logger


@pytest.fixture(scope="session", autouse=True)
def setup_debug_logger():
    """Setup debug logger for tests."""
    os.environ["SWIFTSHADOW_TEST_DEBUG"] = "true"
    setup_logger(level="DEBUG")
    yield
    del os.environ["SWIFTSHADOW_TEST_DEBUG"]


@pytest.fixture(scope="session")
def event_loop() -> Generator[asyncio.AbstractEventLoop, None, None]:
    """创建事件循环"""
    loop = asyncio.get_event_loop_policy().new_event_loop()
    yield loop
    loop.close()


@pytest_asyncio.fixture
async def test_db() -> AsyncGenerator[None, None]:
    """创建测试数据库"""
    # 使用内存数据库
    test_engine = create_async_engine(
        "sqlite+aiosqlite:///:memory:",
        echo=False,
    )

    # 创建表
    async with test_engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)

    # 临时替换全局db实例
    original_engine = db._engine
    original_factory = db._session_factory

    db._engine = test_engine
    db._session_factory = sessionmaker(
        bind=test_engine,
        class_=AsyncSession,
        expire_on_commit=False,
    )

    yield

    # 清理
    await test_engine.dispose()
    db._engine = original_engine
    db._session_factory = original_factory


@pytest_asyncio.fixture
async def sample_task(test_db) -> DownloadTask:
    """创建示例任务"""
    task = DownloadTask(
        url="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        title="Test Video",
        filename="test.mp4",
        save_path="/tmp/test.mp4",
        status=TaskStatus.PENDING,
    )

    async with db.session() as session:
        session.add(task)
        await session.commit()
        await session.refresh(task)

    return task


@pytest.fixture
def temp_download_dir(tmp_path: Path) -> Path:
    """创建临时下载目录"""
    download_dir = tmp_path / "downloads"
    download_dir.mkdir()
    return download_dir
